import React, { useEffect, useRef, useState } from 'react';
import {
  Badge,
  Button, Card,
  Drawer,
  Form,
  Grid,
  Input, PaginationProps, Select,
  Space, Table, Notification,
  Typography
} from '@arco-design/web-react';
import instance from '@/utils/request';
import useLocale from '@/utils/useLocale';
import {
  IconPlus,
  IconRefresh,
  IconSearch
} from '@arco-design/web-react/icon';
import { EnabledOptions } from '@/constants/options';
import { EditMode } from '@/constants/enums';
import { defaultDrawerLayout, defaultDrawerWidth, defaultPaginationProps } from '@/constants/defaults';
import { resolveEnabledName } from '@/constants/functions';
import { OeeConfigResponse, ParameterResponse } from '@/constants/type';
import { TableOperationButtonGroup } from '@/components/common/table_operation_button_group';
import CalculatePanelNumerical from '@/components/CalculatePanel/CalculatePanelNumerical';

const { Row, Col } = Grid;
const locale = {
  'en-US': {},
  'zh-CN': {
    'title.create': '创建OEE配置',
    'title.update': '修改OEE配置',

    'label.enabled': '状态',
    'label.oee_rule': 'OEE规则',
    'label.quality_rule': '质量指数规则',
    'label.availability_rule': '可用性规则',
    'label.performance_rule': '表现性规则',
    'label.device_id': '设备id',

    'placeholder.id': '请输入OEE配置ID',
    'placeholder.oee_rule': '请输入OEE配置规则',
    'placeholder.oee_rule_render': '请输入OEE配置规则',
    'placeholder.oee_rule_edit': '请输入OEE配置规则',
    'placeholder.quality_rule': '请输入质量指数配置规则',
    'placeholder.quality_rule_render': '请输入质量指数配置规则',
    'placeholder.quality_rule_edit': '请输入质量指数配置规则',
    'placeholder.availability_rule': '请输入可用性配置规则',
    'placeholder.availability_rule_render': '请输入可用性配置规则',
    'placeholder.availability_rule_edit': '请输入可用性配置规则',
    'placeholder.performance_rule': '请输入表现性配置规则',
    'placeholder.performance_rule_render': '请输入表现性配置规则',
    'placeholder.performance_rule_edit': '请输入表现性配置规则',
    'placeholder.enabled': '请选择OEE配置状态',

    'columns.id': 'ID',
    'columns.oee_rule_render': 'OEE规则',
    'columns.quality_rule_render': '质量指数规则',
    'columns.availability_rule_render': '可用性规则',
    'columns.performance_rule_render': '表现性规则',
    'columns.enabled': '状态',
    'columns.operations': '操作',

    'button.search': '搜索',
    'button.reset': '重置',
    'button.create': '创建',
    'button.update': '编辑',
    'button.delete': '删除',
    'button.upload': '批量导入',
    'button.download': '下载OEE配置',

    'confirm.title.delete': '确认删除',
    'confirm.content.delete': '删除后将不可恢复！'
  }
};

const SearchForm = (props: {
  onSubmit: (r: Partial<OeeConfigResponse>) => void,
  onReset: () => void,
}) => {
  const t = useLocale(locale);
  const [form] = Form.useForm<OeeConfigResponse>();
  return (
    <Form form={form} style={{ padding: '1rem', background: 'white' }}>
      <Row style={{ display: 'flex' }}>
        <Grid style={{ flexGrow: '1' }} cols={4} colGap={12} rowGap={16}>
          <Grid.GridItem>
            <Form.Item noStyle label={t['columns.id']} field="id">
              <Input placeholder={t['placeholder.id']} allowClear />
            </Form.Item>
          </Grid.GridItem>
          <Grid.GridItem>
            <Form.Item noStyle label={t['columns.enabled']} field="enabled">
              <Select
                placeholder={t['placeholder.enabled']}
                options={EnabledOptions}
                allowClear
              />
            </Form.Item>
          </Grid.GridItem>
        </Grid>
        <Row style={{ display: 'inline-flex', marginLeft: '1rem' }} justify={'center'}>
          <Space direction={'vertical'}>
            <Button type="primary" icon={<IconSearch />} onClick={() => props.onSubmit(form.getFieldsValue())}>
              {t['button.search']}
            </Button>
            <Button icon={<IconRefresh />} onClick={() => {
              form.resetFields();
              props.onReset();
            }}>
              {t['button.reset']}
            </Button>
          </Space>
        </Row>
      </Row>
    </Form>
  );
};

const ModelDrawer = (props: {
  record?: OeeConfigResponse
  visible: boolean;
  toggleVisible: (v: boolean) => void;
  mode: EditMode;
  onFinish: () => void;
  parameters: ParameterResponse[];
}) => {
  const t = useLocale(locale);
  const [form] = Form.useForm();
  const [confirmLoading, setConfirmLoading] = useState(false);
  const [expand, setExpand] = useState<string>();
  const deviceId = useRef<number>();
  const [oeeRuleRender, setOeeRuleRender] = useState<string>('');
  const [availabilityRuleRender, setAvailabilityRule] = useState<string>('');
  const [qualityRuleRender, setQualityRuleRender] = useState<string>('');
  const [performanceRuleRender, setPerformanceRuleRender] = useState<string>('');
  const title = () => {
    switch (props.mode) {
      case EditMode.Create:
        return t['title.create'];
      case EditMode.Update:
        return t['title.update'];
      default:
        return '';
    }
  };

  function onSubmitDrawer() {
    form.validate().then(() => {
      setConfirmLoading(true);
      const data = form.getFields();
      instance
        .post(props.mode === EditMode.Create ? '/api/oee/config/create' : '/api/oee/config/update', data)
        .then((res) => {
          if (res.data.code === 200) {
            // 刷新页面数据
            Notification.success({
              title: res.data.message,
              content: ''
            });
            props.onFinish();
          } else {
            Notification.error({
              title: res.data.message,
              content: res.data.data
            });
          }
        })
        .finally(() => {
          form.resetFields();
          setConfirmLoading(false);
          props.toggleVisible(false);
        });
    });
  }

  function onCancelDrawer() {
    props.toggleVisible(false);
  }

  function fillFormData() {
    form.resetFields();
    switch (props.mode) {
      case EditMode.Update:
        form.setFieldsValue(props.record);
        form.setFieldValue('enabled', props.record?.enabled + '' || 'false');
        form.setFieldValue('deviceId', deviceId.current);
        form.setFieldValue('oeeRule', props.record?.oeeRule);
        form.setFieldValue('oeeRuleEdit', props.record?.oeeRuleEdit);
        form.setFieldValue('oeeRuleRender', props.record?.oeeRuleRender);
        form.setFieldValue('availabilityRule', props.record?.availabilityRule);
        form.setFieldValue('availabilityRuleEdit', props.record?.availabilityRuleEdit);
        form.setFieldValue('availabilityRuleRender', props.record?.availabilityRuleRender);
        form.setFieldValue('qualityRule', props.record?.qualityRule);
        form.setFieldValue('qualityRuleEdit', props.record?.qualityRuleEdit);
        form.setFieldValue('qualityRuleRender', props.record?.qualityRuleRender);
        form.setFieldValue('performanceRule', props.record?.performanceRule);
        form.setFieldValue('performanceRuleEdit', props.record?.performanceRuleEdit);
        form.setFieldValue('performanceRuleRender', props.record?.performanceRuleRender);
        setOeeRuleRender(props.record?.oeeRuleRender);
        setAvailabilityRule(props.record?.availabilityRuleRender);
        setPerformanceRuleRender(props.record?.performanceRuleRender);
        setQualityRuleRender(props.record?.performanceRuleRender);
        break;
      case EditMode.Create:
        form.setFieldValue('enabled', 'true');
        form.setFieldValue('deviceId', deviceId.current);
        form.setFieldValue('oeeRule', '');
        form.setFieldValue('oeeRuleEdit', '');
        form.setFieldValue('oeeRuleRender', '');
        form.setFieldValue('availabilityRule', '');
        form.setFieldValue('availabilityRuleEdit', '');
        form.setFieldValue('availabilityRuleRender', '');
        form.setFieldValue('qualityRule', '');
        form.setFieldValue('qualityRuleEdit', '');
        form.setFieldValue('qualityRuleRender', '');
        form.setFieldValue('performanceRule', '');
        form.setFieldValue('performanceRuleEdit', '');
        form.setFieldValue('performanceRuleRender', '');
        setOeeRuleRender('');
        setAvailabilityRule('');
        setPerformanceRuleRender('');
        setQualityRuleRender('');
        break;
    }
  }

  function ruleItemOperation(field: 'oee' | 'availability' | 'quality' | 'performance', type: 'parameter' | 'delete' | 'clear' | null, value: Partial<ParameterResponse> | string) {
    const updateField = (v1: string, v2: string, v3: string) => {
      form.setFieldValue(`${field}RuleRender`, v1);
      form.setFieldValue(`${field}RuleEdit`, v2);
      form.setFieldValue(`${field}Rule`, v3);
      switch (field) {
        case 'oee':
          setOeeRuleRender(v1);
          break;
        case 'availability':
          setAvailabilityRule(v1);
          break;
        case 'performance':
          setPerformanceRuleRender(v1);
          break;
        case 'quality':
          setQualityRuleRender(v1);
          break;
        default:
          break;
      }
    };
    switch (type) {
      case 'parameter':
        updateField(
          `${form.getFieldValue(`${field}RuleRender`)}${(value as ParameterResponse).name}`,
          `${form.getFieldValue(`${field}RuleEdit`)}\{${(value as ParameterResponse).name},${(value as ParameterResponse).code}\}`,
          `${form.getFieldValue(`${field}Rule`)}#${(value as ParameterResponse).code}`);
        break;
      case 'delete':
        const v = form.getFieldValue(`${field}RuleEdit`);
        let deleteRule = 0;
        let deleteEdit = 0;
        let deleteRender = 0;
        for (let i = v.length - 1, del = 0, flag = false; i >= 0; i--) {
          if (v[i] === '') {
          } else if (v[i] === '}') {
            flag = true;
          } else if (flag && v[i] === '{') {
            const r = v.substring(v.length - del);
            const arr = r.split(',');
            deleteRender = arr[0].length + 1;
            deleteRule = arr[1].length;
            deleteEdit = (v.length - i);
            break;
          } else if (flag && v[i] !== '{') {
            del++;
          } else {
            deleteRule = 1;
            deleteRender = 1;
            deleteEdit = 1;
            break;
          }
        }
        const r = form.getFieldValue(`${field}RuleRender`);
        const e = form.getFieldValue(`${field}RuleEdit`);
        const b = form.getFieldValue(`${field}Rule`);
        updateField(
          r.substring(0, r.length - deleteRender),
          e.substring(0, e.length - deleteEdit),
          b.substring(0, b.length - deleteRule));
        break;
      case 'clear':
        updateField('', '', '');
        break;
      default:
        updateField(
          `${form.getFieldValue(`${field}RuleRender`)}${value}`,
          `${form.getFieldValue(`${field}RuleEdit`)}${value}`,
          `${form.getFieldValue(`${field}Rule`)}${value}`);
        break;
    }
  }

  useEffect(() => {
    try {
      const search = new URLSearchParams(location.search);
      deviceId.current = parseInt(search.get('id'));
      fillFormData();
    } catch (_) {
    }
  }, [props.record, props.mode]);

  return (
    <Drawer
      width={defaultDrawerWidth}
      title={<span>{title()}</span>}
      visible={props.visible}
      confirmLoading={confirmLoading}
      onOk={onSubmitDrawer}
      onCancel={onCancelDrawer}
    >
      <Form {...defaultDrawerLayout} form={form} layout="vertical">
        <Form.Item label={t['label.enabled']} required field="enabled" rules={[{ required: true }]}>
          <Select
            placeholder={t['placeholder.enabled']}
            options={EnabledOptions}
            allowClear
          />
        </Form.Item>
        <Row style={{ margin: '0 0 10px 0' }}>
          <Typography.Text>
            <Typography.Text style={{ color: 'red', marginRight: '8px' }}>
              *
            </Typography.Text>
            <Typography.Text style={{ color: 'rgb( 78, 89, 105 )' }}>
              {t['label.availability_rule']}
            </Typography.Text>
          </Typography.Text>
        </Row>
        <Row>
          <Typography.Text
            onClick={() => setExpand(expand === 'availability' ? '' : 'availability')}
            style={{
              background: '#f2f3f5',
              borderRadius: '3px',
              width: '100%',
              height: '1.8rem',
              padding: '4px 12px'
            }}>{availabilityRuleRender}</Typography.Text>
          <Row style={{
            border: '1px solid #f2f3f5',
            borderTop: '0px solid grey',
            width: '100%',
            borderRadius: '3px',
            borderTopLeftRadius: '0px',
            borderTopRightRadius: '0px',
            background: 'rgba(240,245,245,0.5)',
            fontSize: '0.9rem'
          }}>
            {
              expand === 'availability' &&
              <Col span={24} style={{ padding: '1rem' }}>
                <CalculatePanelNumerical runningParameters parameters={props.parameters}
                                         onChange={(t, v) => ruleItemOperation('availability', t, v)} />
              </Col>
            }
          </Row>
        </Row>
        <Row style={{ margin: '20px 0 10px 0' }}>
          <Typography.Text>
            <Typography.Text style={{ color: 'red', marginRight: '8px' }}>
              *
            </Typography.Text>
            <Typography.Text style={{ color: 'rgb( 78, 89, 105 )' }}>
              {t['label.performance_rule']}
            </Typography.Text>
          </Typography.Text>
        </Row>
        <Row>
          <Typography.Text
            onClick={() => setExpand(expand === 'performance' ? '' : 'performance')}
            style={{
              background: '#f2f3f5',
              borderRadius: '3px',
              width: '100%',
              height: '1.8rem',
              padding: '4px 12px'
            }}>{performanceRuleRender}</Typography.Text>
          <Row style={{
            border: '1px solid #f2f3f5',
            borderTop: '0px solid grey',
            width: '100%',
            borderRadius: '3px',
            borderTopLeftRadius: '0px',
            borderTopRightRadius: '0px',
            background: 'rgba(240,245,245,0.5)',
            fontSize: '0.9rem'
          }}>
            {
              expand === 'performance' &&
              <Col span={24} style={{ padding: '1rem' }}>
                <CalculatePanelNumerical runningParameters parameters={props.parameters}
                                         onChange={(t, v) => ruleItemOperation('performance', t, v)} />
              </Col>
            }
          </Row>
        </Row>
        <Row style={{ margin: '20px 0 10px 0' }}>
          <Typography.Text>
            <Typography.Text style={{ color: 'red', marginRight: '8px' }}>
              *
            </Typography.Text>
            <Typography.Text style={{ color: 'rgb( 78, 89, 105 )' }}>
              {t['label.quality_rule']}
            </Typography.Text>
          </Typography.Text>
        </Row>
        <Row>
          <Typography.Text
            onClick={() => setExpand(expand === 'quality' ? '' : 'quality')}
            style={{
              background: '#f2f3f5',
              borderRadius: '3px',
              width: '100%',
              height: '1.8rem',
              padding: '4px 12px'
            }}>{qualityRuleRender}</Typography.Text>
          <Row style={{
            border: '1px solid #f2f3f5',
            borderTop: '0px solid grey',
            width: '100%',
            borderRadius: '3px',
            borderTopLeftRadius: '0px',
            borderTopRightRadius: '0px',
            background: 'rgba(240,245,245,0.5)',
            fontSize: '0.9rem'
          }}>
            {
              expand === 'quality' &&
              <Col span={24} style={{ padding: '1rem' }}>
                <CalculatePanelNumerical runningParameters parameters={props.parameters}
                                         onChange={(t, v) => ruleItemOperation('quality', t, v)} />
              </Col>
            }
          </Row>
        </Row>
        <Row style={{ margin: '20px 0 10px 0' }}>
          <Typography.Text>
            <Typography.Text style={{ color: 'red', marginRight: '8px' }}>
              *
            </Typography.Text>
            <Typography.Text style={{ color: 'rgb( 78, 89, 105 )' }}>
              {t['label.oee_rule']}
            </Typography.Text>
          </Typography.Text>
        </Row>
        <Row>
          <Typography.Text
            onClick={() => setExpand(expand === 'oee' ? '' : 'oee')}
            style={{
              background: '#f2f3f5',
              borderRadius: '3px',
              width: '100%',
              height: '1.8rem',
              padding: '4px 12px'
            }}>{oeeRuleRender}</Typography.Text>
          <Row style={{
            border: '1px solid #f2f3f5',
            borderTop: '0px solid grey',
            width: '100%',
            borderRadius: '3px',
            borderTopLeftRadius: '0px',
            borderTopRightRadius: '0px',
            background: 'rgba(240,245,245,0.5)',
            fontSize: '0.9rem'
          }}>
            {
              expand === 'oee' &&
              <Col span={24} style={{ padding: '1rem' }}>
                <CalculatePanelNumerical oeeParameters runningParameters parameters={props.parameters}
                                         onChange={(t, v) => ruleItemOperation('oee', t, v)} />
              </Col>
            }
          </Row>
        </Row>
        <Form.Item style={{ display: 'none' }} label={t['label.device_id']} disabled required field="deviceId"
                   rules={[{ required: true }]}>
          <Input placeholder={t['placeholder.device_id']} />
        </Form.Item>
      </Form>
    </Drawer>
  );
};

const OeeConfigPage = () => {
  const t = useLocale(locale);
  const [data, setData] = useState([]);
  const [pagination, setPagination] = useState<PaginationProps>(defaultPaginationProps);
  const [loading, setLoading] = useState(true);
  const [formParams, setFormParams] = useState<Partial<OeeConfigResponse>>({});
  const [visible, setVisible] = useState(false);
  const [editMode, setEditMode] = useState(EditMode.Create);
  const [selectRecord, setSelectRecord] = useState<OeeConfigResponse>();
  const [parameters, setParameters] = useState<ParameterResponse[]>([]);
  const deviceId = useRef<number>();

  function fetchDeviceInfo() {
    if (deviceId.current != null) {
      instance
        .post('/api/device/get', { id: deviceId.current })
        .then((res) => {
          if (res.data.code === 200) {
            setParameters((res.data.data?.model?.parameters || []));
          }
        });
    }
  }

  function fetchData() {
    if (!!deviceId.current) {
      const { current, pageSize } = pagination;
      setLoading(true);
      instance
        .post('/api/oee/config/page', {
          pager: {
            pageNumber: current,
            pageSize
          },
          query: {
            deviceId: deviceId.current,
            ...(formParams || {})
          }
        })
        .then((res) => {
          if (res.data.code === 200) {
            setData(res.data.data.map(it => {
              return {
                ...it,
                privateParameters: (it.parameters || []).filter(iit => !!!iit.common),
                publicParameters: (it.parameters || []).filter(iit => !!iit.common)
              };
            }));
            setPagination({
              ...pagination,
              current,
              pageSize,
              total: res.data.total
            });
          } else {
            Notification.error({
              title: res.data.message,
              content: res.data.data
            });
          }
        }).finally(() => {
        setLoading(false);
      });
    }
  }

  function onDeleteRecord(id: number) {
    setLoading(true);
    instance
      .post('/api/oee/config/delete', { id: id })
      .then((res) => {
        if (res.data.code === 200) {
          Notification.success({
            title: res.data.message,
            content: ''
          });
        } else {
          Notification.error({
            title: res.data.message,
            content: res.data.data
          });
        }
      })
      .finally(() => {
        setLoading(false);
        fetchData();
      });
  }

  function onCreateRecord(record: OeeConfigResponse) {
    setSelectRecord(record);
    setEditMode(EditMode.Create);
    setVisible(true);
  }

  function onUpdateRecord(record: OeeConfigResponse) {
    setSelectRecord(record);
    setEditMode(EditMode.Update);
    setVisible(true);
  }

  useEffect(() => {
    fetchData();
  }, [pagination.current, pagination.pageSize, formParams, deviceId.current]);

  useEffect(() => {
    try {
      const search = new URLSearchParams(location.search);
      deviceId.current = parseInt(search.get('id'));
      fetchDeviceInfo();
    } catch (_) {
    }
  }, []);

  return (
    <Card>
      <SearchForm onSubmit={it => setFormParams(it)}
                  onReset={() => setFormParams(null)} />
      <Row justify={'space-between'}>
        <Space>
          <Button type="primary" icon={<IconPlus />} onClick={() => onCreateRecord(null)}>
            {t['button.create']}
          </Button>
        </Space>
      </Row>
      <Table
        style={{ marginTop: '1rem' }}
        rowKey={record => record.id}
        loading={loading}
        onChange={({ current, pageSize }) => setPagination({ ...pagination, current, pageSize })}
        pagination={pagination}
        columns={[
          {
            title: t['columns.id'],
            dataIndex: 'id'
          },
          {
            title: t['columns.oee_rule_render'],
            dataIndex: 'oeeRuleRender'
          },
          {
            title: t['columns.availability_rule_render'],
            dataIndex: 'availabilityRuleRender'
          },
          {
            title: t['columns.quality_rule_render'],
            dataIndex: 'qualityRuleRender'
          },
          {
            title: t['columns.performance_rule_render'],
            dataIndex: 'performanceRuleRender'
          },
          {
            title: t['columns.enabled'],
            dataIndex: 'enabled',
            render: (value) => {
              return value === true
                ? <Badge status="success" text={resolveEnabledName(value)}></Badge>
                : <Badge status="error" text={resolveEnabledName(value)}></Badge>;
            }
          },
          {
            title: t['columns.remark'],
            dataIndex: 'remark'
          },
          {
            title: t['columns.operations'],
            headerCellStyle: { paddingLeft: '15px' },
            render: (_, record: OeeConfigResponse) => {
              return <TableOperationButtonGroup
                record={record}
                onUpdate={() => onUpdateRecord(record)}
                onDelete={() => onDeleteRecord(record?.id)}
              />;
            }
          }
        ]}
        data={data}
      />
      <ModelDrawer
        visible={visible}
        toggleVisible={setVisible}
        parameters={parameters}
        mode={editMode}
        record={selectRecord}
        onFinish={fetchData}
      />
    </Card>
  );
};

export default OeeConfigPage;
